/*
 * Configuracoes.java
 *
 * Created on 22 de Maio de 2007, 00:38
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package org.jerm.Interface;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.net.URL;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import javax.swing.*;

import org.jerm.Interface.JGraph_Diagrama.Aresta;
import org.jerm.Interface.JGraph_Diagrama.Entidade;
import org.jerm.Interface.JGraph_Diagrama.Heranca;
import org.jerm.Interface.JGraph_Diagrama.MyGraph;
import org.jerm.Interface.JGraph_Diagrama.MyModel;
import org.jerm.Interface.JGraph_Diagrama.Relacionamento;
import org.jerm.Mapeamento.Atributos.Atributo;
import org.jerm.Mapeamento.Atributos.AtributoSerial;
import org.jerm.Mapeamento.Atributos.FK;
import org.jerm.Mapeamento.Tabelas.Tabela;
import org.jgraph.JGraph;
import org.jgraph.graph.DefaultPort;
import org.jgraph.graph.Port;

/**
 *
 * @author Crepaldi
 */
public class Tabelas_old extends JPanel
{
    private MyGraph graph;
    protected Principal Principal;
    
    private Object[] primos, naoprimos, arestas;    // vetores auxiliares para navegacao no DER
    HashMap<String,Tabela> relacoes;                // tabelas reultantes do mapeamento
    Object todos_blocos[];                          // vetor de blocos do DER
    Entidade entidade;                              // entidade auxiliar para manipulacao do DER
    Relacionamento relacionamento;                  // relacionamento auxiliar para manipulacao do DER
    FK fk = new FK();                               // Chave estrangeira auxiliar para mapeamento
    Tabela tab;
    
    /** Creates a new instance of Configuracoes */
    public Tabelas_old (JGraph graph,Principal Principal)
    {
        super();
        this.graph = (MyGraph) graph;
        this.Principal=Principal;
        this.relacoes = new HashMap();
        
        AbstractAction action = new AbstractAction(""){
                public void actionPerformed(ActionEvent e) {
                    System.out.println("Executar!!!\n\n");
                    mapeamento();
                    
                }
        };
        URL iconUrl = getClass().getClassLoader().getResource("org/jerm/Interface/icons/plus.gif");
        JButton exe = new JButton("");
        exe.setAction (action);
        exe.setIcon (new ImageIcon(iconUrl));
        this.add(exe);
        
    }

    public String getToolTip(){
        return "<html>Blue Wavy Line border art crew:<br>&nbsp;&nbsp;&nbsp;Bill Pauley<br>" +
                "&nbsp;&nbsp;&nbsp;Cris St. Aubyn<br>" +
                "&nbsp;&nbsp;&nbsp;Ben Wronsky<br>" +
                "&nbsp;&nbsp;&nbsp;Nathan Walrath<br>" +
                "&nbsp;&nbsp;&nbsp;Tommy Adams, special consultant</html>";
    }    

    /* Metodo que mapeia apenas as entidades fortes de um DER
     *
     *	mapeia_entidade_forte() {
     *      Para cada vertice v
     *          criar relacao com todos os atributos
     *              se v[] herdar de alguem
     *                  adiciona chave da classe pai a relacao
     *  }
     */
    private void mapeia_entidade_forte() throws Exception{
        
        boolean achou_pai_heranca = false;
        int i, j, k, l, m;
        
        //recebe vetor de blocos
        todos_blocos = (Object[])  graph.getGraphLayoutCache ().getCells(false,true,false,false);
        
        // recebe blocos nas pontas das arestas
        i=0;
        //entidade_aux = new Entidade()
        while (i < todos_blocos.length){
          
            // verifica se e entidade
            if (todos_blocos[i].getClass() == Entidade.class){
                entidade = (Entidade) todos_blocos[i];
                if ((!entidade.isFraca()) && (!graph.isFilhoHeranca((Object)todos_blocos[i]))){
                    
                    // cria uma nova relacao com o nome igual ao nome da entidade
                    relacoes.put(graph.convertValueToString(todos_blocos[i]),new Tabela(graph.convertValueToString(todos_blocos[i])));
                    
                    // pega todos os atributos nao primos
                    naoprimos = entidade.valuesArrayAtributos();
                    
                    // adiciona atributos nao primos a relacao
                    for (j = 0; j < naoprimos.length; j++){
                        relacoes.get(graph.convertValueToString(todos_blocos[i])).addAtributo((Atributo) naoprimos[j]);
                    }

                    // pega todos os atributos primos
                    primos = entidade.valuesArrayAtributosPrimos();
                    
                    // adiciona atributos primos a relacao
                    for (j = 0; j < primos.length; j++){
                        relacoes.get(graph.convertValueToString(todos_blocos[i])).addPrimo((Atributo) primos[j]);
                    }

                    // Imprime resultado do mapeamento para TESTES
                    System.out.println("\n\nMapeamento de Entidades binarias fortes nao associativas");
                    System.out.println(relacoes.get(graph.convertValueToString(todos_blocos[i])).getMER());
                    System.out.println(relacoes.get(graph.convertValueToString(todos_blocos[i])).getSQL());
                    
                }else{
                    // se nao for entidade FORTE, ignore-o
                    i++;
                    continue;
                }
                
            }else{
                // se nao for entidade, volta pro inicio do loop em busca do proximo bloco
                i++;
                continue;
            }

            //proxima aresta
            i++;
        }
        

        // recebe blocos nas pontas das arestas
        i=0;
        //entidade_aux = new Entidade()
        while (i < todos_blocos.length){
          
            // verifica se e entidade
            if (todos_blocos[i].getClass() == Entidade.class){
                entidade = (Entidade) todos_blocos[i];
                if ((!entidade.isFraca()) && (graph.isFilhoHeranca((Object)todos_blocos[i]))){
                    
                    // cria uma nova relacao com o nome igual ao nome da entidade
                    relacoes.put(graph.convertValueToString(todos_blocos[i]),new Tabela(graph.convertValueToString(todos_blocos[i])));

                    // pega todos os atributos nao primos
                    naoprimos = entidade.valuesArrayAtributos();
                    
                    // adiciona atributos nao primos a relacao
                    for (j = 0; j < naoprimos.length; j++){
                        relacoes.get(graph.convertValueToString(todos_blocos[i])).addAtributo((Atributo) naoprimos[j]);
                    }

                    // pega todos os atributos primos
                    primos = entidade.valuesArrayAtributosPrimos();
                    
                    // adiciona atributos primos a relacao
                    for (j = 0; j < primos.length; j++){
                        relacoes.get(graph.convertValueToString(todos_blocos[i])).addPrimo((Atributo) primos[j]);
                    }

                    // Varre DER para determinar se a entidade forte ATUAL herda de alguma outra entidade.
                    k=0;
                    while (k < todos_blocos.length){
                        // verifica se e HERANCA
                        if (todos_blocos[k].getClass() == Heranca.class){

                            // pega todas as arestas que tem a origem na heranca
                            arestas = (Object[]) graph.getArestas(todos_blocos[k],Aresta.SOURCE);

                            l = 0;
                            while (l < arestas.length){
                                
                                // Se o bloco que sai de uma heranca tiver como target bloco de entidade forte atual
                                // a entidade forte herda de alguem.
                                if (((DefaultPort) ((Aresta) arestas[l]).getTarget()).getUserObject() == todos_blocos[i]){

                                    // pega a aresta q liga o pai da heranca a heranca
                                    arestas = (Object[]) graph.getArestas(todos_blocos[k],Aresta.TARGET);

                                    // pega entidade pai da heranca
                                    entidade = ((Entidade)((DefaultPort)((Aresta)arestas[0]).getSource()).getUserObject());

                                    // pega todos os atributos primos
                                    primos = entidade.valuesArrayAtributosPrimos();

                                    // adiciona atributos primos do pai da heranca a relacao
                                    for (j = 0; j < primos.length; j++){
                                        relacoes.get(graph.convertValueToString(todos_blocos[i])).addFKPrimo(((Tabela)relacoes.get(graph.convertValueToString(entidade))),(AtributoSerial)primos[j]);
                                    }
                                    
                                    // depois que acha pai da heranca, encerra-se o mapeamento
                                    achou_pai_heranca = true;                                    
                                    break;
                                }else{
                                    // se a entidade forte nao herda dessa Heranca, ignore-a
                                    l++;
                                    continue;
                                }

                            }
                            
                            // depois que acha pai da heranca, encerra-se o mapeamento
                            if (achou_pai_heranca) break;                            
                            
                            k++;
                        }else{
                            // se nao for do tipo heranca, ignore-o
                            k++;
                            continue;
                        }
                    }

                    // Imprime resultado do mapeamento para TESTES
                    System.out.println("\n\nMapeamento de Entidades binarias fortes nao associativas");
                    System.out.println(relacoes.get(graph.convertValueToString(todos_blocos[i])).getMER());
                    System.out.println(relacoes.get(graph.convertValueToString(todos_blocos[i])).getSQL());                    
                    
                }else{
                    // se nao for entidade FORTE, ignore-o
                    i++;
                    continue;
                }

            }else{
                // se nao for entidade, volta pro inicio do loop em busca do proximo bloco
                i++;
                continue;
            }

            //proxima aresta
            i++;
        }
        
    }

    /* Metodo que mapeia apenas as entidades fracas de um DER
     *
     *	mapeia_entidade_fraca() {
     *      Para cada vertice v
     *          criar relacao com todos os atributos fracos
     *          adicionar a relacao as chaves da entidade forte
     *          se v[] herdar de alguem
     *              adicionar chaves da relacao pai
     *  }
     */
    private void mapeia_entidade_fraca() throws Exception{
        
        boolean achou_pai_heranca = false;
        int i, j, k, l, m;
        
        //recebe vetor de blocos
        todos_blocos = (Object[])  graph.getGraphLayoutCache ().getCells(false,true,false,false);
        
        // recebe blocos nas pontas das arestas
        i=0;
        //entidade_aux = new Entidade()
        while (i < todos_blocos.length){
          
            // verifica se e entidade
            if (todos_blocos[i].getClass() == Entidade.class){
                entidade = (Entidade) todos_blocos[i];
                //verifica se e fraca e nao herda de ninguem
                if ((entidade.isFraca()) && (!graph.isFilhoHeranca((Object)todos_blocos[i]))){

                    // cria uma nova relacao com o nome igual ao nome da entidade
                    relacoes.put(graph.convertValueToString(todos_blocos[i]),new Tabela(graph.convertValueToString(todos_blocos[i])));

                    // pega todos os atributos nao primos
                    naoprimos = entidade.valuesArrayAtributos();
                    
                    // adiciona atributos nao primos a relacao
                    for (j = 0; j < naoprimos.length; j++){
                        relacoes.get(graph.convertValueToString(todos_blocos[i])).addAtributo((Atributo) naoprimos[j]);
                    }

                    // pega todos os atributos primos
                    primos = entidade.valuesArrayAtributosPrimos();
                    
                    // adiciona atributos primos a relacao
                    for (j = 0; j < primos.length; j++){
                        relacoes.get(graph.convertValueToString(todos_blocos[i])).addPrimo((Atributo) primos[j]);
                    }

                    // pega todas as arestas que tem o target na entidade fraca
                    arestas = (Object[]) graph.getArestas(todos_blocos[i],Aresta.TARGET);
                    
                    // procurar a aresta que liga a entidade fraca ao relacionamento fraco
                    k=0;
                    while (k < arestas.length){
                        if (((Aresta) arestas[k]).isTotal() ){

                            // pega o relacionamento fraco
                            relacionamento = ((Relacionamento)((DefaultPort)((Aresta)arestas[k]).getSource()).getUserObject());

                            // pega todas as arestas que tem a origem no rel. fraco da ent. fraca
                            arestas = (Object[]) graph.getArestas(relacionamento,Aresta.SOURCE);
                            
                            // procura entidade forte que se liga ao relacionamento fraco
                            if (!((Aresta) arestas[0]).isTotal() ){

                                // pega a ent. forte do rel fraco da ent. fraca
                                entidade = ((Entidade)((DefaultPort)((Aresta)arestas[0]).getTarget()).getUserObject());
                                
                            }else{
                                // pega a ent. forte do rel fraco da ent. fraca
                                entidade = ((Entidade)((DefaultPort)((Aresta)arestas[1]).getTarget()).getUserObject());
                            }

                            // pega todos os atributos primos
                            primos = entidade.valuesArrayAtributosPrimos();

                            // adiciona atributos primos da entidade forte
                            for (l = 0; l < primos.length; l++){
                                relacoes.get(graph.convertValueToString(todos_blocos[i])).addFKPrimo(((Tabela)relacoes.get(graph.convertValueToString(entidade))),(AtributoSerial)primos[l]);
                            }
                            
                            // so tem uma aresta que liga ao relacionamento fraco
                            break;
                        }else{
                            // se nao for aresta q liga ao relacionamento fraco, ignore-o
                            k++;
                            continue;
                        }
                        
                    }

                    // Imprime resultado do mapeamento para TESTES
                    System.out.println("\n\nMapeamento de Entidades binarias fracas nao associativas");
                    System.out.println(relacoes.get(graph.convertValueToString(todos_blocos[i])).getMER());
                    System.out.println(relacoes.get(graph.convertValueToString(todos_blocos[i])).getSQL());
                    
                }else{
                    // se nao for entidade FORTE, ignore-o
                    i++;
                    continue;
                }
                
            }else{
                // se nao for entidade, volta pro inicio do loop em busca do proximo bloco
                i++;
                continue;
            }

            //proxima aresta
            i++;
        }

        // recebe blocos nas pontas das arestas
        i=0;
        //entidade_aux = new Entidade()
        while (i < todos_blocos.length){
          
            // verifica se e entidade
            if (todos_blocos[i].getClass() == Entidade.class){
                entidade = (Entidade) todos_blocos[i];
                
                //verifica se e fraca e se herda de alguem
                if ((entidade.isFraca()) && (graph.isFilhoHeranca((Object)todos_blocos[i]))){

                    // cria uma nova relacao com o nome igual ao nome da entidade
                    relacoes.put(graph.convertValueToString(todos_blocos[i]),new Tabela(graph.convertValueToString(todos_blocos[i])));

                    // pega todos os atributos nao primos
                    naoprimos = entidade.valuesArrayAtributos();
                    
                    // adiciona atributos nao primos a relacao
                    for (j = 0; j < naoprimos.length; j++){
                        relacoes.get(graph.convertValueToString(todos_blocos[i])).addAtributo((Atributo) naoprimos[j]);
                    }

                    // pega todos os atributos primos
                    primos = entidade.valuesArrayAtributosPrimos();
                    
                    // adiciona atributos primos a relacao
                    for (j = 0; j < primos.length; j++){
                        relacoes.get(graph.convertValueToString(todos_blocos[i])).addPrimo((Atributo) primos[j]);
                    }

                    // pega todas as arestas que tem o target na entidade fraca
                    arestas = (Object[]) graph.getArestas(todos_blocos[i],Aresta.TARGET);
                    
                    // procurar a aresta que liga a entidade fraca ao relacionamento fraco
                    k=0;
                    while (k < arestas.length){
                        if (((Aresta) arestas[k]).isTotal() ){

                            // pega o relacionamento fraco
                            relacionamento = ((Relacionamento)((DefaultPort)((Aresta)arestas[k]).getSource()).getUserObject());

                            // pega todas as arestas que tem a origem no rel. fraco da ent. fraca
                            arestas = (Object[]) graph.getArestas(relacionamento,Aresta.SOURCE);
                            
                            // procura entidade forte que se liga ao relacionamento fraco
                            if (!((Aresta) arestas[0]).isTotal() ){
                                
                                // pega a ent. forte do rel fraco da ent. fraca
                                entidade = ((Entidade)((DefaultPort)((Aresta)arestas[0]).getTarget()).getUserObject());
                                
                            }else{
                                // pega a ent. forte do rel fraco da ent. fraca
                                entidade = ((Entidade)((DefaultPort)((Aresta)arestas[1]).getTarget()).getUserObject());
                            }

                            // pega todos os atributos primos
                            primos = entidade.valuesArrayAtributosPrimos();
                    
                            // adiciona atributos primos a relacao
                            for (l = 0; l < primos.length; l++){
                                relacoes.get(graph.convertValueToString(todos_blocos[i])).addFKPrimo(((Tabela)relacoes.get(graph.convertValueToString(entidade))),(AtributoSerial)primos[l]);
                            }
                            
                            // so tem uma aresta que liga ao relacionamento fraco
                            break;
                        }else{
                            // se nao for aresta q liga ao relacionamento fraco, ignore-o
                            k++;
                            continue;
                        }
                        
                    }

                    // Varre DER para determinar se a entidade fraca ATUAL herda de alguma outra entidade.
                    k=0;
                    while (k < todos_blocos.length){
                        // verifica se e HERANCA
                        if (todos_blocos[k].getClass() == Heranca.class){

                            // pega todas as arestas que tem a origem na heranca
                            arestas = (Object[]) graph.getArestas(todos_blocos[k],Aresta.SOURCE);

                            l = 0;
                            while (l < arestas.length){
                                
                                // Se o bloco que sai de uma heranca tiver como target bloco de entidade fraco atual
                                // a entidade forte herda de alguem.
                                if (((DefaultPort) ((Aresta) arestas[l]).getTarget()).getUserObject() == todos_blocos[i]){

                                    // pega a aresta q liga o pai da heranca a heranca
                                    arestas = (Object[]) graph.getArestas(todos_blocos[k],Aresta.TARGET);

                                    // pega entidade pai da heranca
                                    entidade = ((Entidade)((DefaultPort)((Aresta)arestas[0]).getSource()).getUserObject());
                                    
                                    // pega todos os atributos primos
                                    primos = entidade.valuesArrayAtributosPrimos();
                    
                                    // adiciona atributos primos a relacao
                                    for (j = 0; j < primos.length; j++){
                                        relacoes.get(graph.convertValueToString(todos_blocos[i])).addFKPrimo(((Tabela)relacoes.get(graph.convertValueToString(entidade))),(AtributoSerial)primos[j]);
                                    }
                                    
                                    // depois que acha pai da heranca, encerra-se o mapeamento
                                    achou_pai_heranca = true;                                    
                                    break;
                                }else{
                                    // se a entidade forte nao herda dessa Heranca, ignore-a
                                    l++;
                                    continue;
                                }

                            }
                            
                            // depois que acha pai da heranca, encerra-se o mapeamento
                            if (achou_pai_heranca) break;                            
                            
                            k++;
                        }else{
                            // se nao for do tipo heranca, ignore-o
                            k++;
                            continue;
                        }

                    }

                    // Imprime resultado do mapeamento para TESTES
                    System.out.println("\n\nMapeamento de Entidades binarias fracas nao associativas");
                    System.out.println(relacoes.get(graph.convertValueToString(todos_blocos[i])).getMER());
                    System.out.println(relacoes.get(graph.convertValueToString(todos_blocos[i])).getSQL());

                }else{
                    // se nao for entidade FORTE, ignore-o
                    i++;
                    continue;
                }
                
            }else{
                // se nao for entidade, volta pro inicio do loop em busca do proximo bloco
                i++;
                continue;
            }

            //proxima aresta
            i++;
        }        
        
        
        
        
    }

    /* Metodo que mapeia apenas os relacionamentos binarios de um DER
     *
     *	mapeia_relacionamento_binario() {
     *  	Para cada vertice v
     *  		se cardinalidade for 1:N
     *                      inserir na relacao do lado N a chave do lado 1
     *                      adicionar a relacao as chaves estrang. da entidade forte
     *                      adicionar chaves da relacao pai
     *      		senao se cardinalidade for 1:1
     *  			se alguma delas tiver card. minima 0
     *                              inserir na rel. do outro lado chave estrang. da rel. com card 0 para evitar nulos
     *                          senao inserir em uma relacao qualuqer a chave da outra
     *                          adicionar a relacao escolhida acima os atributos do relacionamento, se houver
     *                  se cardinalidade for N:N
     *                      criar uma nova relacao com as chaves estrang. primarias de cada entidade envolvida
     *                      adicione os atributos do relacionamento na nova relacao
     *
     *  }
     */
    public void mapeia_relacionamento_binario() throws Exception{
        int i, j;
        Object[] aux;
        Entidade e1, e2; //ent. auxiliares

        // pega todos os relacionamentos binarios
        todos_blocos = graph.getCells(Relacionamento.class,2,Aresta.SOURCE);
        
        // percorre relacionamentos binarios procurando os auto-relacionamentos
        i=0;
        while (i < todos_blocos.length){

            // pega todas as arestas que tem a origem na heranca
            arestas = (Object[]) graph.getArestas(todos_blocos[i],Aresta.SOURCE); 
            
            // pega relacionamento
            relacionamento = (Relacionamento) todos_blocos[i];
            
            // verifica se nao e auto-relacionamento, se nao e fraca, s nao e associativa
            if ((((Aresta)arestas[0]).getTarget() != ((Aresta)arestas[1]).getTarget()) && (!relacionamento.isTotal()) && (!relacionamento.isAssociativa())){

                // pega todos adjacentes da rel. binaria forte, nao auto relacionada e nao associativa
                aux = graph.getAdjacentes(todos_blocos[i],Aresta.SOURCE);
                
                // entidade unaria
                e1 = ((Entidade)((DefaultPort)((Aresta)arestas[0]).getTarget()).getUserObject());
                e2 = ((Entidade)((DefaultPort)((Aresta)arestas[1]).getTarget()).getUserObject());
                
                // pega atributos nao primos do relacionamento
                naoprimos = relacionamento.valuesArrayAtributos();

                // se for 1:1
                if ((((Aresta)arestas[0]).getMax() == 1) && (((Aresta)arestas[1]).getMax() == 1)) {

                    // se entidade 1 tiver cardinalidade minima zero, recebe primos de entidade 2
                    // caso contrario, entidade 2 recebe primos de entidade 1
                    if (((Aresta)arestas[0]).getMin() == 0) {

                        // pega todos os atributos primos
                        primos = e2.valuesArrayAtributosPrimos();
                    
                        // adiciona atributos primos a entidade
                        for (j = 0; j < primos.length; j++){
                            relacoes.get(graph.convertValueToString(e1)).addFK(((Tabela)relacoes.get(graph.convertValueToString(e2))),(AtributoSerial)primos[j]);
                        }
                        
                        // adiciona atributos nao primos a entidade
                        for (j = 0; j < naoprimos.length; j++){
                            relacoes.get(graph.convertValueToString(e1)).addAtributo((Atributo)naoprimos[j]);
                        }
            
                    }else{

                        // pega todos os atributos primos
                        primos = e1.valuesArrayAtributosPrimos();
                    
                        // adiciona atributos primos a relacao
                        for (j = 0; j < primos.length; j++){
                            relacoes.get(graph.convertValueToString(e2)).addFK(((Tabela)relacoes.get(graph.convertValueToString(e1))),(AtributoSerial)primos[j]);
                        }
                        
                        // adiciona atributos nao primos a entidade
                        for (j = 0; j < naoprimos.length; j++){
                            relacoes.get(graph.convertValueToString(e2)).addAtributo((Atributo)naoprimos[j]);
                        }
                        
                 }
                    
                }else if (((((Aresta)arestas[0]).getMax() == 1) && (((Aresta)arestas[1]).getMax() > 1))  || (((((Aresta)arestas[0]).getMax() > 1) && (((Aresta)arestas[1]).getMax() == 1)))){
                // se for 1 : n
                    
                    // se entidade 1 for n, recebe primos de entidade 2
                    // caso contrario, entidade 2 recebe primos de entidade 1
                    if (((Aresta)arestas[0]).getMax() > 1) {

                        // pega todos os atributos primos
                        primos = e2.valuesArrayAtributosPrimos();
                    
                        // adiciona atributos primos a relacao
                        for (j = 0; j < primos.length; j++){
                            relacoes.get(graph.convertValueToString(e1)).addFK(((Tabela)relacoes.get(graph.convertValueToString(e2))),(AtributoSerial)primos[j]);
                        }
                        
                        // adiciona atributos nao primos a entidade
                        for (j = 0; j < naoprimos.length; j++){
                            relacoes.get(graph.convertValueToString(e1)).addAtributo((Atributo)naoprimos[j]);
                        }
                        
                            
                    }else{

                        // pega todos os atributos primos
                        primos = e1.valuesArrayAtributosPrimos();
                    
                        // adiciona atributos primos a relacao
                        for (j = 0; j < primos.length; j++){
                            relacoes.get(graph.convertValueToString(e2)).addFK(((Tabela)relacoes.get(graph.convertValueToString(e1))),(AtributoSerial)primos[j]);
                        }
                        
                        // adiciona atributos nao primos a entidade
                        for (j = 0; j < naoprimos.length; j++){
                            relacoes.get(graph.convertValueToString(e2)).addAtributo((Atributo)naoprimos[j]);
                        }
                      
                    }
                    
                }else if ((((Aresta)arestas[0]).getMax() > 1) && (((Aresta)arestas[1]).getMax() > 1)){
                // se for n : n

                    // cria uma nova relacao com o nome igual ao nome do relacionamento
                    relacoes.put(graph.convertValueToString(relacionamento),new Tabela(graph.convertValueToString(relacionamento)));

                    // pega todos os atributos primos
                    primos = e1.valuesArrayAtributosPrimos();
                    
                    // adiciona atributos primos a relacao
                    for (j = 0; j < primos.length; j++){
                        relacoes.get(graph.convertValueToString(relacionamento)).addFKPrimo(((Tabela)relacoes.get(graph.convertValueToString(e1))),(AtributoSerial)primos[j]);
                    }
                    
                    // pega todos os atributos primos
                    primos = e2.valuesArrayAtributosPrimos();
                    
                    // adiciona atributos primos a relacao
                    for (j = 0; j < primos.length; j++){
                        relacoes.get(graph.convertValueToString(relacionamento)).addFKPrimo(((Tabela)relacoes.get(graph.convertValueToString(e2))),(AtributoSerial)primos[j]);
                    }
                    
                    // adiciona atributos nao primos a entidade
                    for (j = 0; j < naoprimos.length; j++){
                        relacoes.get(graph.convertValueToString(relacionamento)).addAtributo((Atributo)naoprimos[j]);
                    }
                    
                    // Imprime resultado do mapeamento para TESTES
                    System.out.println("\n\nMapeamento de Relacionamentos binarios fortes nao associativos");
                    System.out.println(relacoes.get(graph.convertValueToString(relacionamento)).getMER());
                    System.out.println(relacoes.get(graph.convertValueToString(relacionamento)).getSQL());
                    
                }

                // Imprime resultado do mapeamento para TESTES
                System.out.println("\n\nMapeamento de Relacionamentos binarios fortes nao associativos");
                System.out.println(relacoes.get(graph.convertValueToString(e1)).getMER());
                System.out.println(relacoes.get(graph.convertValueToString(e1)).getSQL());
                
                System.out.println(relacoes.get(graph.convertValueToString(e2)).getMER());
                System.out.println(relacoes.get(graph.convertValueToString(e2)).getSQL());                

                // proximo relacioamento binario
                i++;
            }else{
                i++;
                continue;
            }
            
        }//while

    }

    /* Metodo que mapeia entidades associativas
     *
     *  mapeia_entidade_associativa
     *      criar uma nova relacao
     *      se houver chave na entidade associativa, usa-la
     *      caso contrario, usar as chaves estrang. primarias de cada entidade envolvida
     *      adicione os atributos do relacionamento na nova relacao
     */
    public void mapeia_entidade_associativa() throws Exception{
    int i, j;
        Object[] aux;
        Entidade e1, e2; //ent. auxiliares

        // pega todos os relacionamentos binarios
        todos_blocos = graph.getCells(Relacionamento.class,2,Aresta.SOURCE);
        
        // percorre relacionamentos binarios procurando os auto-relacionamentos
        i=0;
        while (i < todos_blocos.length){

            // pega todas as arestas que tem a origem na heranca
            arestas = (Object[]) graph.getArestas(todos_blocos[i],Aresta.SOURCE); 
            
            // pega relacionamento
            relacionamento = (Relacionamento) todos_blocos[i];
            
            // verifica se nao e auto-relacionamento, se nao e fraca, se e associativa
            if ((((Aresta)arestas[0]).getTarget() != ((Aresta)arestas[1]).getTarget()) && (!relacionamento.isTotal()) && (relacionamento.isAssociativa())){

                // pega todos adjacentes da rel. binaria forte, nao auto relacionada e nao associativa
                aux = graph.getAdjacentes(todos_blocos[i],Aresta.SOURCE);
                
                // cria uma nova relacao com o nome igual ao nome do relacionamento
                relacoes.put(graph.convertValueToString(relacionamento),new Tabela(graph.convertValueToString(relacionamento)));
                
                // pega atributos primos/nao primos do relacionamento
                naoprimos = relacionamento.valuesArrayAtributos();
                primos = relacionamento.valuesArrayAtributosPrimos();

                // adiciona atributos nao primos a entidade
                for (j = 0; j < naoprimos.length; j++){
                    relacoes.get(graph.convertValueToString(relacionamento)).addAtributo((Atributo)naoprimos[j]);
                }
                
                // se entidade associativa tiver chave, use-a
                if (primos.length > 0) {

                    // adiciona atributos primos a relacao
                    for (j = 0; j < primos.length; j++){
                        relacoes.get(graph.convertValueToString(relacionamento)).addPrimo((AtributoSerial)primos[j]);
                    }
                    
                }else{

                    // entidades
                    e1 = ((Entidade)((DefaultPort)((Aresta)arestas[0]).getTarget()).getUserObject());
                    e2 = ((Entidade)((DefaultPort)((Aresta)arestas[1]).getTarget()).getUserObject());
                    
                    // pega todos os atributos primos
                    primos = e1.valuesArrayAtributosPrimos();
                    
                    // adiciona atributos primos a relacao
                    for (j = 0; j < primos.length; j++){
                        relacoes.get(graph.convertValueToString(relacionamento)).addFKPrimo(((Tabela)relacoes.get(graph.convertValueToString(e1))),(AtributoSerial)primos[j]);
                    }

                    // pega todos os atributos primos
                    primos = e2.valuesArrayAtributosPrimos();
                    
                    // adiciona atributos primos a relacao
                    for (j = 0; j < primos.length; j++){
                        relacoes.get(graph.convertValueToString(relacionamento)).addFKPrimo(((Tabela)relacoes.get(graph.convertValueToString(e2))),(AtributoSerial)primos[j]);
                    }

                }

                // Imprime resultado do mapeamento para TESTES
                System.out.println("\n\nMapeamento de Entidades Associativas fortes");
                System.out.println(relacoes.get(graph.convertValueToString(relacionamento)).getMER());
                System.out.println(relacoes.get(graph.convertValueToString(relacionamento)).getSQL());
                
                // proximo relacioamento binario
                i++;
            }else{
                i++;
                continue;
            }
            
        }//while
        
    }
            
    /* Metodo que mapeia apenas os relacionamnetos unarios de um DER
     *
     *	mapeia_relacionamento_unario() {
     *      se for 1:N ou 1:1
     *		Adiciona a ENTIDADE uma copia das chave primarias dela mesmo como estrangeiras
     *      senao se for N:N
     *		cria uma nova relacao
     *		adiciona a ela 2 copias das chaves primarias da entidade
     *		adiciona a elas os atributos do relacionamento, se houver
     *  }
     */
    public void mapeia_relacionamento_unario() throws Exception{
        int i, j;
        Object[] aux;
        
        // pega todos os relacionamentos binarios
        todos_blocos = graph.getCells(Relacionamento.class,2,Aresta.SOURCE);
        
        // percorre relacionamentos binarios procurando os auto-relacionamentos
        i=0;
        while (i < todos_blocos.length){

            // pega todas as arestas que tem a origem no rel. binario
            arestas = (Object[]) graph.getArestas(todos_blocos[i],Aresta.SOURCE); 
            
            // verifica se e auto-relacionamento
            if (((Aresta)arestas[0]).getTarget() == ((Aresta)arestas[1]).getTarget()){

                // pega todos adjacentes ao auto relacionamento
                aux = graph.getAdjacentes(todos_blocos[i],Aresta.SOURCE);
                
                // entidade unaria
                entidade = ((Entidade)((DefaultPort)((Aresta)arestas[0]).getTarget()).getUserObject());

                // se for 1:1 ou 1:n ou n:1
                if (((((Aresta)arestas[0]).getMax() == 1) && (((Aresta)arestas[1]).getMax() == 1)) || (((((Aresta)arestas[0]).getMax() == 1) && (((Aresta)arestas[1]).getMax() > 1)) || ((((Aresta)arestas[0]).getMax() > 1) && (((Aresta)arestas[1]).getMax() == 1)))){

                    // pega todos os atributos primos da entidade unaria
                    primos = relacoes.get(graph.convertValueToString(entidade)).getPrimo();

                    // adiciona atributos primos da entidade unaria como estrangeira
                    for (j = 0; j < primos.length; j++){
                        relacoes.get(graph.convertValueToString(entidade)).addFK(((Tabela)relacoes.get(graph.convertValueToString(entidade))),(AtributoSerial)primos[j]);
                    }
                    
                    // pega todos os atributos primos da entidade unaria
                    primos = relacoes.get(graph.convertValueToString(entidade)).getFKPrimo();
                    // adiciona atributos primos da entidade unaria como estrangeira
                    for (j = 0; j < primos.length; j++){
                        relacoes.get(graph.convertValueToString(entidade)).addFK(((FK)primos[j]));
                    }                    

                    // Imprime resultado do mapeamento para TESTES
                    System.out.println("\n\nMapeamento de Relacionamentos unarios fortes nao associativos");
                    System.out.println(relacoes.get(graph.convertValueToString(entidade)).getMER());
                    System.out.println(relacoes.get(graph.convertValueToString(entidade)).getSQL());
                
                }else if ((((Aresta)arestas[0]).getMax() > 1) && (((Aresta)arestas[1]).getMax() > 1)){
                    // se for n:n

                    // cria uma nova relacao com o nome igual ao nome do relacionamento
                    relacoes.put(graph.convertValueToString(todos_blocos[i]),new Tabela(graph.convertValueToString(todos_blocos[i])));

                    // pega todos os atributos primos do relacionamento
                    primos = ((Relacionamento)todos_blocos[i]).valuesArrayAtributosPrimos();

                    // adiciona atributos primos do relacionamento
                    for (j = 0; j < primos.length; j++){
                        relacoes.get(graph.convertValueToString(todos_blocos[i])).addPrimo((Atributo)primos[j]);
                    }
                    
                    // pega todos os atributos nao primos
                    naoprimos = ((Relacionamento)todos_blocos[i]).valuesArrayAtributos();

                    // adiciona atributos nao primos do relacionamento
                    for (j = 0; j < naoprimos.length; j++){
                        relacoes.get(graph.convertValueToString(todos_blocos[i])).addAtributo((Atributo)naoprimos[j]);
                    }

                    // pega todos os atributos primos da entidade unaria
                    primos = relacoes.get(graph.convertValueToString(entidade)).getPrimo();

                    // adiciona atributos primos da entidade unaria como estrangeira
                    for (j = 0; j < primos.length; j++){
                        relacoes.get(graph.convertValueToString(todos_blocos[i])).addFKPrimo(((Tabela)relacoes.get(graph.convertValueToString(entidade))),(AtributoSerial)primos[j]);
                        relacoes.get(graph.convertValueToString(todos_blocos[i])).addFKPrimo(((Tabela)relacoes.get(graph.convertValueToString(entidade))),(AtributoSerial)primos[j]);                        
                    }
                    
                    // pega todos os atributos primos da entidade unaria
                    primos = relacoes.get(graph.convertValueToString(entidade)).getFKPrimo();

                    // adiciona atributos primos da entidade unaria como estrangeira
                    for (j = 0; j < primos.length; j++){
                        relacoes.get(graph.convertValueToString(todos_blocos[i])).addFKPrimo(((FK)primos[j]));
                        relacoes.get(graph.convertValueToString(todos_blocos[i])).addFKPrimo(((FK)primos[j]));
                    }
                    
                    // Imprime resultado do mapeamento para TESTES
                    System.out.println("\n\nMapeamento de Relacionamentos unarios fortes nao associativos");
                    System.out.println(relacoes.get(graph.convertValueToString(todos_blocos[i])).getMER());
                    System.out.println(relacoes.get(graph.convertValueToString(todos_blocos[i])).getSQL());
                }

            }else{
                i++;
                continue;
            }

            //proximo relacionamento
            i++;
        }
        
        
    }
    
    /* Metodo que mapeia apenas os relacionamnetos ternarios de um DER
     *
     *	mapeia_relacionamento_ternario() {
     *      Para cada vertice v
     *		converter relacionamento para associativo
     *      Mapeia_entidade_associativa();
     *  }
     */
    public void mapeia_relacionamento_ternario(){
        
        
        System.out.println("\n\nMapeamento de Relacionamentos ternarios");
    }
    
    /* Metodo que mapeia apenas as agregacoes de um DER
     *
     *	mapeia_agregacao() {
     *      Para cada vertice v
     *		criar rel. com todas as chaves de relacionamento e relacoes dentro da agregacao como c. primaria
     *		adicinar atributos da agregacao, se houver
     *  }
     */
    public void mapeia_agregacao(){
        System.out.println("Mapeamento de agregacao nao implementada. Nao faz parte da especificacao");
    }    
    
    /* 
     *  Classe que executa mapeamento completo de um diagrama
     */
    public void mapeamento(){
        try {

            /*
             *  Sequencia de passos para mapear todos os elementos do DER
             */
            mapeia_entidade_forte();
            mapeia_entidade_fraca();
            mapeia_relacionamento_unario();
            mapeia_relacionamento_binario();
            mapeia_entidade_associativa();
            mapeia_relacionamento_ternario();
            mapeia_agregacao();
            
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        
    }

    private void add(AbstractAction abstractAction) {
        throw new UnsupportedOperationException("Bad Bad computeiro. No donut for you!!!");
    }

}
